package org.ourgrid.common.executor.vbox;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.ourgrid.common.executor.Executor;
import org.ourgrid.common.executor.ExecutorException;
import org.ourgrid.common.executor.ExecutorHandle;
import org.ourgrid.common.executor.ExecutorResult;
import org.ourgrid.common.executor.IntegerExecutorHandle;
import org.ourgrid.common.executor.SandBoxEnvironment;
import org.ourgrid.common.executor.config.ExecutorConfiguration;

import br.edu.ufcg.lsd.commune.container.logging.CommuneLogger;

public class VBoxExecutor implements Executor {
	
	private static final long serialVersionUID = 4L;
	
	private transient final CommuneLogger logger;
	
	private final SandBoxEnvironment sandBoxEnv;
	
	/**
	 * @param sandBoxEnv
	 * @param logger 
	 */
	public VBoxExecutor(SandBoxEnvironment sandBoxEnv, CommuneLogger logger){
		this.sandBoxEnv = sandBoxEnv;
		this.logger = logger;
	}

	public void beginAllocation() throws ExecutorException {
		// not implemented
	}

	public void chmod(File file, String perm) throws ExecutorException {
		// not implemented
	}

	public ExecutorHandle execute(String dirName, String command,
			Map<String, String> envVars) throws ExecutorException {
		
		if ( dirName == null || command == null ) {
			throw new ExecutorException( "Invalid parameters: " + dirName + ", " + command );
		}
		
		logger.debug( "Requested to execute command: " + command + ", Dir Name: " + dirName );
		
		sandBoxEnv.executeRemoteCommand(dirName, command, envVars);
		
		return new IntegerExecutorHandle(new Random().nextInt());
	}

	public ExecutorHandle execute(String dirName, String command)
			throws ExecutorException {
		return execute(dirName, command, new HashMap<String, String>());
	}

	public void finishExecution() throws ExecutorException {
		sandBoxEnv.finishExecution();
	}

	public ExecutorResult getResult(ExecutorHandle handle)
			throws ExecutorException {
		logger.debug( "Requested to get result: " + " handle: " + handle);
		
		while (!sandBoxEnv.hasExecutionFinished()) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				logger.debug("Command was killed");
				throw new ExecutorException(e);
			}
		}
			
		return sandBoxEnv.getResult();
	}

	public void kill(ExecutorHandle handle) throws ExecutorException {
		sandBoxEnv.kill();
	}

	public void setConfiguration(ExecutorConfiguration executorConfiguratrion) {
		sandBoxEnv.setConfiguration(executorConfiguratrion);
	}
}